#nullable enable

using System.Globalization;

namespace System;

public static class NumberExtensions
{
    /// <summary>
    /// 返回从指定的 <see cref="sbyte"/> 创建的文化无关的 <see cref="string"/>。
    /// </summary>
    /// <param name="number">要转换为字符串的数字。</param>
    public static string ToTechnicalString(this sbyte number) => number.ToString(CultureInfo.InvariantCulture);

    /// <summary>
    /// 返回从指定的 <see cref="byte"/> 创建的文化无关的 <see cref="string"/>。
    /// </summary>
    /// <param name="number">要转换为字符串的数字。</param>
    public static string ToTechnicalString(this byte number) => number.ToString(CultureInfo.InvariantCulture);

    /// <summary>
    /// 返回从指定的 <see cref="short"/> 创建的文化无关的 <see cref="string"/>。
    /// </summary>
    /// <param name="number">要转换为字符串的数字。</param>
    public static string ToTechnicalString(this short number) => number.ToString(CultureInfo.InvariantCulture);

    /// <summary>
    /// 返回从指定的 <see cref="ushort"/> 创建的文化无关的 <see cref="string"/>。
    /// </summary>
    /// <param name="number">要转换为字符串的数字。</param>
    public static string ToTechnicalString(this ushort number) => number.ToString(CultureInfo.InvariantCulture);

    /// <summary>
    /// 返回从指定的 <see cref="int"/> 创建的文化无关的 <see cref="string"/>。
    /// </summary>
    /// <param name="number">要转换为字符串的数字。</param>
    public static string ToTechnicalString(this int number) => number.ToString(CultureInfo.InvariantCulture);

    /// <summary>
    /// 返回从指定的 <see cref="uint"/> 创建的文化无关的 <see cref="string"/>。
    /// </summary>
    /// <param name="number">要转换为字符串的数字。</param>
    public static string ToTechnicalString(this uint number) => number.ToString(CultureInfo.InvariantCulture);

    /// <summary>
    /// 返回从指定的 <see cref="long"/> 创建的文化无关的 <see cref="string"/>。
    /// </summary>
    /// <param name="number">要转换为字符串的数字。</param>
    public static string ToTechnicalString(this long number) => number.ToString(CultureInfo.InvariantCulture);

    /// <summary>
    /// 返回从指定的 <see cref="ulong"/> 创建的文化无关的 <see cref="string"/>。
    /// </summary>
    /// <param name="number">要转换为字符串的数字。</param>
    public static string ToTechnicalString(this ulong number) => number.ToString(CultureInfo.InvariantCulture);

    /// <summary>
    /// 返回从指定的 <see cref="decimal"/> 创建的文化无关的 <see cref="string"/>。
    /// </summary>
    /// <param name="number">要转换为字符串的数字。</param>
    public static string ToTechnicalString(this decimal number) => number.ToString(CultureInfo.InvariantCulture);

    /// <summary>
    /// 返回从指定的 <see cref="IConvertible"/> 创建的文化无关的 <see cref="string"/>。
    /// </summary>
    /// <param name="number">要转换为字符串的数字。</param>
    public static string? ToTechnicalString(this IConvertible? number) => number?.ToString(CultureInfo.InvariantCulture);

    /// <summary>
    /// 如果 <paramref name="number"/> 可以解析为 <see cref="int"/> 则返回结果。如果解析失败则返回 -1。
    /// </summary>
    public static int ToTechnicalInt(this string number) =>
        int.TryParse(number, NumberStyles.Any, CultureInfo.InvariantCulture, out var result) ? result : -1;

    /// <summary>
    /// 返回给定 <see cref="int"/> 中的位数。
    /// </summary>
    /// <param name="number">要计算位数的数字。</param>
    public static int DigitCount(this int number) => (int)Math.Log10(number) + 1;

    /// <summary>
    /// 返回一个 <see cref="string"/>，通过用零填充左侧来右对齐给定 <see cref="int"/> 的数字，以达到指定的总长度。
    /// </summary>
    /// <param name="length">结果 <see cref="string"/> 中的总位数。</param>
    /// <returns>
    /// 给定 <see cref="int"/> 的 <see cref="string"/> 表示，左侧用零填充。
    /// </returns>
    public static string PadZeroes(this int number, int length) =>
        number.ToString("D" + length.ToTechnicalString(), CultureInfo.InvariantCulture);
}
